package com.sheng.leetcode.year2022.month09.day10;

import org.junit.Test;

/**
 * @author liusheng
 * @date 2022/09/13
 *<p>
 * 669. 修剪二叉搜索树<p>
 *<p>
 * 给你二叉搜索树的根节点 root ，同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树，<p>
 * 使得所有节点的值在[low, high]中。修剪树 不应该改变保留在树中的元素的相对结构 (即，如果没有被移除，原有的父代子代关系都应当保留)。 <p>
 * 可以证明，存在唯一的答案。<p>
 * 所以结果应当返回修剪好的二叉搜索树的新的根节点。注意，根节点可能会根据给定的边界发生改变。<p>
 *<p>
 * 示例 1：<p>
 * 输入：root = [1,0,2], low = 1, high = 2<p>
 * 输出：[1,null,2]<p>
 * <p>
 * 示例 2：<p>
 * 输入：root = [3,0,4,null,2,null,null,1], low = 1, high = 3<p>
 * 输出：[3,2,null,1]<p>
 *<p>
 * 提示：<p>
 *<p>
 * 树中节点数在范围 [1, 104] 内<p>
 * 0 <= Node.val <= 104<p>
 * 树中每个节点的值都是 唯一 的<p>
 * 题目数据保证输入是一棵有效的二叉搜索树<p>
 * 0 <= low <= high <= 104<p>
 *<p>
 * 来源：力扣（LeetCode）<p>
 * 链接：<a href="https://leetcode.cn/problems/trim-a-binary-search-tree">...</a><p>
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。<p>
 */
public class LeetCode0669 {

    @Test
    public void test01() {
//        TreeNode root = new TreeNode(1);
//        root.left = new TreeNode(0);
//        root.right = new TreeNode(2);
//        int low = 1, high = 2;

//        TreeNode root = new TreeNode(3);
//        root.right = new TreeNode(4);
//        TreeNode left = new TreeNode(0);
//        TreeNode left1 = new TreeNode(2);
//        left1.left = new TreeNode(1);
//        left.right = left1;
//        root.left = left;
//        int low = 1, high = 3;

        TreeNode root = new TreeNode(3);
        root.right = new TreeNode(4);
        TreeNode left = new TreeNode(2);
        left.left = new TreeNode(1);
        root.left = left;
        int low = 1, high = 1;
        TreeNode treeNode = new Solution().trimBST(root, low, high);
        System.out.println(treeNode);
    }
}
class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
        // 注意事项：如果左结点小余最小边界，那么左结点的左结点也一并去除，同理右结点大于最大边界，右结点的右结点也一并去除
        if (root == null) {
            return null;
        }
        if (root.val >= low) {
            if (root.val <= high) {
                // 满足边界条件
                if (root.left != null) {
                    root.left = trimBST(root.left, low, high);
                }
                if (root.right != null) {
                    root.right = trimBST(root.right, low, high);
                }
            } else {
                // 当前结点大于最大边界，只考虑左结点即可
                if (root.left != null) {
                    root = trimBST(root.left, low, high);
                } else {
                    root = null;
                }
            }
        } else {
            // 当前结点小余最小边界，只考虑右结点即可
            if (root.right != null) {
                root = trimBST(root.right, low, high);
            } else {
                root = null;
            }
        }
        return root;
    }
}

// Definition for a binary tree node.
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode() {}
    TreeNode(int val) { this.val = val; }
    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}
